package com.ruoyi.erp.service.impl;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.erp.domain.*;
import com.ruoyi.erp.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.erp.mapper.ProjectBonusMapper;
import com.ruoyi.common.core.text.Convert;
import org.springframework.transaction.annotation.Transactional;

/**
 * 项目提成Service业务层处理
 * 
 * @author sauger
 * @date 2022-04-21
 */
@Service
public class ProjectBonusServiceImpl implements IProjectBonusService 
{
    @Autowired
    private ProjectBonusMapper projectBonusMapper;
    @Autowired
    private IProjectBonusUserService bonusUserService;
    @Autowired
    private IReceivableAccountService receivableAccountService;
    @Autowired
    private IProjectBonusConfigService configService;
    @Autowired
    private IProjectBonusExcludeService excludeService;
    /**
     * 查询项目提成
     * 
     * @param id 项目提成主键
     * @return 项目提成
     */
    @Override
    public ProjectBonus selectProjectBonusById(Integer id)
    {
        return projectBonusMapper.selectProjectBonusById(id);
    }

    /**
     * 查询项目提成列表
     * 
     * @param projectBonus 项目提成
     * @return 项目提成
     */
    @Override
    public List<ProjectBonus> selectProjectBonusList(ProjectBonus projectBonus)
    {
        return projectBonusMapper.selectProjectBonusList(projectBonus);
    }

    /**
     * 新增项目提成
     * 
     * @param projectBonus 项目提成
     * @return 结果
     */
    @Override
    public int insertProjectBonus(ProjectBonus projectBonus)
    {
        return projectBonusMapper.insertProjectBonus(projectBonus);
    }

    /**
     * 修改项目提成
     * 
     * @param projectBonus 项目提成
     * @return 结果
     */
    @Override
    public int updateProjectBonus(ProjectBonus projectBonus)
    {
        return projectBonusMapper.updateProjectBonus(projectBonus);
    }

    /**
     * 批量删除项目提成
     * 
     * @param ids 需要删除的项目提成主键
     * @return 结果
     */
    @Override
    public int deleteProjectBonusByIds(String ids)
    {
        return projectBonusMapper.deleteProjectBonusByIds(Convert.toStrArray(ids));
    }

    /**
     * 删除项目提成信息
     * 
     * @param id 项目提成主键
     * @return 结果
     */
    @Override
    public int deleteProjectBonusById(Integer id)
    {
        return projectBonusMapper.deleteProjectBonusById(id);
    }

    @Override
    @Transactional
    public void updateBonusByDuration(Date beginTime, Date endTime) {
        projectBonusMapper.deleteProjectBonusByDuration(beginTime, endTime);
        projectBonusMapper.deleteProjectBonusExcludeByDuration(beginTime, endTime);
        ReceivableAccount search = new ReceivableAccount();
        search.getParams().put("beginTime", DateUtils.parseDateToStr("yyyy-MM-dd",beginTime));
        search.getParams().put("endTime", DateUtils.parseDateToStr("yyyy-MM-dd",endTime));
        List<ReceivableAccount> receivableAccountList = receivableAccountService.selectReceivableAccountList(search);
        receivableAccountList.stream().filter(f->!f.getPlan().getPlanType().equals("staffing")).forEach(receivableAccount -> {
            updateNoneStaffingBonusByReceivable(receivableAccount);
        });
        //处理外派
        List<VirtualStaffingReceivable> staffingReceivables = projectBonusMapper.selectStaffingReceivable(beginTime, endTime);
        staffingReceivables.stream().forEach(staffingReceivable -> {
            updateStaffingBonusByStaffingReceivable(staffingReceivable);
        });
    }

    /**
     * 根据收款更新提成
     *
     * @param receivableAccount
     */
    @Override
    public void updateBonusByReceivable(ReceivableAccount receivableAccount) {
        if (receivableAccount.getPlan().getPlanType().equals("staffing")){
            updateStaffingBonusByReceivable(receivableAccount);
        }else{
            updateNoneStaffingBonusByReceivable(receivableAccount);
        }
    }

    private void updateStaffingBonusByStaffingReceivable(VirtualStaffingReceivable staffingReceivable)
    {
        ProjectBonusUser search = new ProjectBonusUser();
        search.setProjectId(staffingReceivable.getProjectId());
        List<ProjectBonusUser> users = bonusUserService.selectProjectBonusUserList(search);
        if (users.isEmpty()){
            return;
        }
        StringBuilder sb = new StringBuilder();
        BigDecimal bonusRate ;
        //计算提成比例
        if (staffingReceivable.getPlanReceiveDate().compareTo(staffingReceivable.getReceiveDate()) < 0){
            //收款过期
            sb.append("收款过期：期望收款时间: ").append(DateUtils.parseDateToStr("yyyy-MM-dd",staffingReceivable.getPlanReceiveDate()));
            sb.append(";实际收款时间: ").append(DateUtils.parseDateToStr("yyyy-MM-dd",staffingReceivable.getReceiveDate())).append(";");
            bonusRate = BigDecimal.ZERO;
        }else {
            bonusRate = configService.getBonusRateByProfitRate(staffingReceivable.getProfitRate());
            sb.append("账单毛利率: ").append(staffingReceivable.getProfitRate()).append(";");
        }

        BigDecimal baseAccount = staffingReceivable.getAmount();//计算提成的金额

        //处理报销金额
        if (staffingReceivable.getExpenseAmount() != null && staffingReceivable.getExpenseAmount().compareTo(BigDecimal.ZERO)>0){
            ProjectBonusExclude searchExclude = new ProjectBonusExclude();
            searchExclude.setBillId(staffingReceivable.getMonthBillId());
            ProjectBonusExclude exclude = excludeService.groupProjectBonusExcludeByBill(searchExclude);
            BigDecimal needExclude = BigDecimal.ZERO;
            if ( exclude == null || exclude.getAmount() == null ){
                needExclude = staffingReceivable.getExpenseAmount();
            }else if(exclude.getAmount().compareTo(staffingReceivable.getExpenseAmount()) < 0) {
                //以前未扣完
                needExclude = staffingReceivable.getExpenseAmount().subtract(exclude.getAmount());
            }
            if (needExclude.compareTo(BigDecimal.ZERO) > 0){
                baseAccount = baseAccount.subtract(needExclude);
                ProjectBonusExclude newExclude = new ProjectBonusExclude();
                newExclude.setBillId(staffingReceivable.getMonthBillId());
                newExclude.setAmount(needExclude);
                newExclude.setReceivableId(staffingReceivable.getReceivableId());
                excludeService.insertProjectBonusExclude(newExclude);
                sb.append("扣除报销费用: ").append(needExclude).append(";");
            }
        }

        BigDecimal bonusAmount = baseAccount.multiply(bonusRate).divide(BigDecimal.valueOf(100), 2,BigDecimal.ROUND_HALF_UP);

        users.stream().forEach(user->{
            ProjectBonus bonus = new ProjectBonus();
            bonus.setUserId(user.getUserId());
            bonus.setProjectId(staffingReceivable.getProjectId());
            bonus.setReceivableId(staffingReceivable.getReceivableId());
            bonus.setBonusAmount(bonusAmount);
            bonus.setReceiveAmount(staffingReceivable.getAmount());
            bonus.setReceiveDate(staffingReceivable.getReceiveDate());
            bonus.setExtra(sb.toString());
            bonus.setBonusRate(bonusRate.doubleValue());
            bonus.setGenerateType("auto");
            bonus.setBonusDate(staffingReceivable.getReceiveDate());
            projectBonusMapper.insertProjectBonus(bonus);
        });
    }

    private void updateStaffingBonusByReceivable(ReceivableAccount receivableAccount)
    {

    }

    /**
     * 非外派项目的提成计算
     * @param receivableAccount
     */
    private void updateNoneStaffingBonusByReceivable(ReceivableAccount receivableAccount)
    {
        ProjectBonusUser search = new ProjectBonusUser();
        search.setProjectId(receivableAccount.getProjectId());
        List<ProjectBonusUser> users = bonusUserService.selectProjectBonusUserList(search);
        if (users.isEmpty()){
            return;
        }
        SimpleDateFormat format = new SimpleDateFormat("yyyy_MM-dd");
        users.stream().forEach(user->{
            ProjectBonus bonus = new ProjectBonus();
            bonus.setUserId(user.getUserId());
            bonus.setProjectId(receivableAccount.getProjectId());
            bonus.setReceivableId(receivableAccount.getId());
            bonus.setReceiveAmount(receivableAccount.getReceiveAmount());
            bonus.setReceiveDate(receivableAccount.getReceiveTime());
            bonus.setGenerateType("auto");
            if (receivableAccount.getReceiveTime().compareTo(receivableAccount.getPlan().getPlanReceiveDate()) > 0){
                //过期
                bonus.setBonusAmount(BigDecimal.ZERO);
                bonus.setBonusRate(Double.valueOf(0));
                bonus.setExtra("收款过期：期望收款时间:" + format.format(receivableAccount.getPlan().getPlanReceiveDate()) + "; 实际收款时间:"
                + format.format(receivableAccount.getReceiveTime()));
            }else {
                bonus.setBonusRate(user.getBonusRate());
                bonus.setBonusAmount(receivableAccount.getReceiveAmount().multiply(BigDecimal.valueOf(user.getBonusRate())).divide(BigDecimal.valueOf(200),2,BigDecimal.ROUND_HALF_UP));
                bonus.setExtra("收款剩余50%， 收尾款后发放");
                projectBonusMapper.insertProjectBonus(bonus);
                bonus.setId(null);
                bonus.setExtra("收款剩的50%");
            }
            bonus.setBonusDate(receivableAccount.getReceiveTime());
            projectBonusMapper.insertProjectBonus(bonus);
        });
    }

    @Override
    public List<ProjectBonus> groupProjectBonusByUser(ProjectBonus projectBonus) {
        return projectBonusMapper.groupProjectBonusListByUser(projectBonus);
    }
}
